#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>

struct Point3D {
    double x, y, z, index;
};

void normalizePoints(std::vector<Point3D>& points) {
    if (points.empty()) return;

    // Step 1: Determine the bounding box
    double xMin = points[0].x, xMax = points[0].x;
    double yMin = points[0].y, yMax = points[0].y;
    double zMin = points[0].z, zMax = points[0].z;

    for (const auto& point : points) {
        xMin = std::min(xMin, point.x);
        xMax = std::max(xMax, point.x);
        yMin = std::min(yMin, point.y);
        yMax = std::max(yMax, point.y);
        zMin = std::min(zMin, point.z);
        zMax = std::max(zMax, point.z);
    }

    // Step 2: Calculate the center and translate
    double cx = (xMin + xMax) / 2.0;
    double cy = (yMin + yMax) / 2.0;
    double cz = (zMin + zMax) / 2.0;

    for (auto& point : points) {
        point.x -= cx;
        point.y -= cy;
        point.z -= cz;
    }

    // Step 3: Scale to unit size
    double L = std::max({xMax - xMin, yMax - yMin, zMax - zMin});
    if (L == 0) L = 1; // Avoid division by zero

    for (auto& point : points) {
        point.x /= L;
        point.y /= L;
        point.z /= L;
    }
}

int main() {
    std::ifstream inputFile("D:/wins-desktop/pcl_geo1/dat/fault.txt");
    std::ofstream outputFile("fault_output.txt");
    std::vector<Point3D> points;
    double x, y, z, index;

    // Read points from input file
    if (!inputFile.is_open()) {
        std::cerr << "Failed to open input file." << std::endl;
        return -1;
    }

    std::cout << "Start reading points..." << std::endl;
    while (inputFile >> x >> y >> index >> z) {
        std::cout << "------------------" << x << std::endl;
        points.push_back({x, y, index, z});
    }
    std::cout << "Finished reading points. Total: " << points.size() << std::endl;

    // Normalize points
    normalizePoints(points);

    // Write normalized points to output file
    if (!outputFile.is_open()) {
        std::cerr << "Failed to open output file." << std::endl;
        return -1;
    }

    std::cout << "Start writing normalized points..." << std::endl;
    for (const auto& point : points) {
        outputFile << point.x << " " << point.y << " " << index <<" " << point.z << "\n";
    }
    std::cout << "Finished writing normalized points." << std::endl;

    inputFile.close();
    outputFile.close();

    std::cout << "Normalization complete. Check output.txt for results.\n";

    return 0;
}